package com.fr.base.core.antlr;

import com.fr.base.core.antlr.collections.impl.BitSet;
import com.fr.base.core.antlr.collections.impl.Vector;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.StringTokenizer;

public class Tool
{
  public static String version = "";
  ToolErrorHandler errorHandler = new DefaultToolErrorHandler(???);
  protected boolean hasError = false;
  boolean genDiagnostics = false;
  boolean genDocBook = false;
  boolean genHTML = false;
  protected String outputDir = ".";
  protected String grammarFile;
  transient Reader f = new InputStreamReader(System.in);
  protected String literalsPrefix = "LITERAL_";
  protected boolean upperCaseMangledLiterals = false;
  protected NameSpace nameSpace = null;
  protected String namespaceAntlr = null;
  protected String namespaceStd = null;
  protected boolean genHashLines = true;
  protected boolean noConstructors = false;
  private BitSet cmdLineArgValid = new BitSet();

  public String getGrammarFile()
  {
    return this.grammarFile;
  }

  public boolean hasError()
  {
    return this.hasError;
  }

  public NameSpace getNameSpace()
  {
    return this.nameSpace;
  }

  public String getNamespaceStd()
  {
    return this.namespaceStd;
  }

  public String getNamespaceAntlr()
  {
    return this.namespaceAntlr;
  }

  public boolean getGenHashLines()
  {
    return this.genHashLines;
  }

  public String getLiteralsPrefix()
  {
    return this.literalsPrefix;
  }

  public boolean getUpperCaseMangledLiterals()
  {
    return this.upperCaseMangledLiterals;
  }

  public void setFileLineFormatter(FileLineFormatter paramFileLineFormatter)
  {
    FileLineFormatter.setFormatter(paramFileLineFormatter);
  }

  protected void checkForInvalidArguments(String[] paramArrayOfString, BitSet paramBitSet)
  {
    for (int i = 0; i < paramArrayOfString.length; ++i)
      if (!(paramBitSet.member(i)))
        warning("invalid command-line argument: " + paramArrayOfString[i] + "; ignored");
  }

  public void copyFile(String paramString1, String paramString2)
    throws IOException
  {
    File localFile1 = new File(paramString1);
    File localFile2 = new File(paramString2);
    BufferedReader localBufferedReader = null;
    BufferedWriter localBufferedWriter = null;
    try
    {
      if ((!(localFile1.exists())) || (!(localFile1.isFile())))
        throw new FileCopyException("FileCopy: no such source file: " + paramString1);
      if (!(localFile1.canRead()))
        throw new FileCopyException("FileCopy: source file is unreadable: " + paramString1);
      if (localFile2.exists())
      {
        if (localFile2.isFile())
        {
          localObject1 = new DataInputStream(System.in);
          if (localFile2.canWrite())
            break label268;
          throw new FileCopyException("FileCopy: destination file is unwriteable: " + paramString2);
        }
        throw new FileCopyException("FileCopy: destination is not a file: " + paramString2);
      }
      Object localObject1 = parent(localFile2);
      if (!(((File)localObject1).exists()))
        throw new FileCopyException("FileCopy: destination directory doesn't exist: " + paramString2);
      if (!(((File)localObject1).canWrite()))
        throw new FileCopyException("FileCopy: destination directory is unwriteable: " + paramString2);
      label268: localBufferedReader = new BufferedReader(new FileReader(localFile1));
      localBufferedWriter = new BufferedWriter(new FileWriter(localFile2));
      char[] arrayOfChar = new char[1024];
      while (true)
      {
        int i = localBufferedReader.read(arrayOfChar, 0, 1024);
        if (i == -1)
          break;
        localBufferedWriter.write(arrayOfChar, 0, i);
      }
    }
    finally
    {
      if (localBufferedReader != null)
        try
        {
          localBufferedReader.close();
        }
        catch (IOException localIOException1)
        {
        }
      if (localBufferedWriter != null)
        try
        {
          localBufferedWriter.close();
        }
        catch (IOException localIOException2)
        {
        }
    }
  }

  public void doEverythingWrapper(String[] paramArrayOfString)
  {
    int i = doEverything(paramArrayOfString);
    System.exit(i);
  }

  public int doEverything(String[] paramArrayOfString)
  {
    com.fr.base.core.antlr.preprocessor.Tool localTool = new com.fr.base.core.antlr.preprocessor.Tool(this, paramArrayOfString);
    boolean bool = localTool.preprocess();
    String[] arrayOfString = localTool.preprocessedArgList();
    processArguments(arrayOfString);
    if (!(bool))
      return 1;
    this.f = getGrammarReader();
    ANTLRLexer localANTLRLexer = new ANTLRLexer(this.f);
    TokenBuffer localTokenBuffer = new TokenBuffer(localANTLRLexer);
    LLkAnalyzer localLLkAnalyzer = new LLkAnalyzer(this);
    MakeGrammar localMakeGrammar = new MakeGrammar(this, paramArrayOfString, localLLkAnalyzer);
    try
    {
      ANTLRParser localANTLRParser = new ANTLRParser(localTokenBuffer, localMakeGrammar, this);
      localANTLRParser.setFilename(this.grammarFile);
      localANTLRParser.grammar();
      if (hasError())
        fatalError("Exiting due to errors.");
      checkForInvalidArguments(arrayOfString, this.cmdLineArgValid);
      String str = "com.fr.base.core.antlr." + getLanguage(localMakeGrammar) + "CodeGenerator";
      try
      {
        CodeGenerator localCodeGenerator = (CodeGenerator)Utils.createInstanceOf(str);
        localCodeGenerator.setBehavior(localMakeGrammar);
        localCodeGenerator.setAnalyzer(localLLkAnalyzer);
        localCodeGenerator.setTool(this);
        localCodeGenerator.gen();
      }
      catch (ClassNotFoundException localClassNotFoundException)
      {
        panic("Cannot instantiate code-generator: " + str);
      }
      catch (InstantiationException localInstantiationException)
      {
        panic("Cannot instantiate code-generator: " + str);
      }
      catch (IllegalArgumentException localIllegalArgumentException)
      {
        panic("Cannot instantiate code-generator: " + str);
      }
      catch (IllegalAccessException localIllegalAccessException)
      {
        panic("code-generator class '" + str + "' is not accessible");
      }
    }
    catch (RecognitionException localRecognitionException)
    {
      fatalError("Unhandled parser error: " + localRecognitionException.getMessage());
    }
    catch (TokenStreamException localTokenStreamException)
    {
      fatalError("TokenStreamException: " + localTokenStreamException.getMessage());
    }
    return 0;
  }

  public void error(String paramString)
  {
    this.hasError = true;
    System.err.println("error: " + paramString);
  }

  public void error(String paramString1, String paramString2, int paramInt1, int paramInt2)
  {
    this.hasError = true;
    System.err.println(FileLineFormatter.getFormatter().getFormatString(paramString2, paramInt1, paramInt2) + paramString1);
  }

  public String fileMinusPath(String paramString)
  {
    String str = System.getProperty("file.separator");
    int i = paramString.lastIndexOf(str);
    if (i == -1)
      return paramString;
    return paramString.substring(i + 1);
  }

  public String getLanguage(MakeGrammar paramMakeGrammar)
  {
    if (this.genDiagnostics)
      return "Diagnostic";
    if (this.genHTML)
      return "HTML";
    if (this.genDocBook)
      return "DocBook";
    return paramMakeGrammar.language;
  }

  public String getOutputDirectory()
  {
    return this.outputDir;
  }

  private static void help()
  {
    System.err.println("usage: java antlr.Tool [args] file.g");
    System.err.println("  -o outputDir       specify output directory where all output generated.");
    System.err.println("  -glib superGrammar specify location of supergrammar file.");
    System.err.println("  -debug             launch the ParseView debugger upon parser invocation.");
    System.err.println("  -html              generate a html file from your grammar.");
    System.err.println("  -docbook           generate a docbook sgml file from your grammar.");
    System.err.println("  -diagnostic        generate a textfile with diagnostics.");
    System.err.println("  -trace             have all rules call traceIn/traceOut.");
    System.err.println("  -traceLexer        have lexer rules call traceIn/traceOut.");
    System.err.println("  -traceParser       have parser rules call traceIn/traceOut.");
    System.err.println("  -traceTreeParser   have tree parser rules call traceIn/traceOut.");
    System.err.println("  -h|-help|--help    this message");
  }

  public static void main(String[] paramArrayOfString)
  {
    System.err.println("ANTLR Parser Generator   Version 2.7.7 (2006-11-01)   1989-2005");
    version = "2.7.7 (2006-11-01)";
    try
    {
      int j;
      int i = 0;
      if (paramArrayOfString.length == 0)
        i = 1;
      else
        for (j = 0; j < paramArrayOfString.length; ++j)
          if ((paramArrayOfString[j].equals("-h")) || (paramArrayOfString[j].equals("-help")) || (paramArrayOfString[j].equals("--help")))
          {
            i = 1;
            break;
          }
      if (i != 0)
      {
        help();
      }
      else
      {
        Tool localTool = new Tool();
        localTool.doEverything(paramArrayOfString);
        localTool = null;
      }
    }
    catch (Exception localException)
    {
      System.err.println(System.getProperty("line.separator") + System.getProperty("line.separator"));
      System.err.println("#$%%*&@# internal error: " + localException.toString());
      System.err.println("[complain to nearest government official");
      System.err.println(" or send hate-mail to parrt@antlr.org;");
      System.err.println(" please send stack trace with report.]" + System.getProperty("line.separator"));
      localException.printStackTrace();
    }
  }

  public PrintWriter openOutputFile(String paramString)
    throws IOException
  {
    if (this.outputDir != ".")
    {
      File localFile = new File(this.outputDir);
      if (!(localFile.exists()))
        localFile.mkdirs();
    }
    return new PrintWriter(new PreservingFileWriter(this.outputDir + System.getProperty("file.separator") + paramString));
  }

  public Reader getGrammarReader()
  {
    BufferedReader localBufferedReader = null;
    try
    {
      if (this.grammarFile != null)
        localBufferedReader = new BufferedReader(new FileReader(this.grammarFile));
    }
    catch (IOException localIOException)
    {
      fatalError("cannot open grammar file " + this.grammarFile);
    }
    return localBufferedReader;
  }

  public void reportException(Exception paramException, String paramString)
  {
    System.err.println(paramString + ": " + paramException.getMessage());
  }

  public void reportProgress(String paramString)
  {
    System.out.println(paramString);
  }

  public void fatalError(String paramString)
  {
    System.err.println(paramString);
    Utils.error(paramString);
  }

  /**
   * @deprecated
   */
  public void panic()
  {
    fatalError("panic");
  }

  /**
   * @deprecated
   */
  public void panic(String paramString)
  {
    fatalError("panic: " + paramString);
  }

  public File parent(File paramFile)
  {
    String str = paramFile.getParent();
    if (str == null)
    {
      if (paramFile.isAbsolute())
        return new File(File.separator);
      return new File(System.getProperty("user.dir"));
    }
    return new File(str);
  }

  public static Vector parseSeparatedList(String paramString, char paramChar)
  {
    StringTokenizer localStringTokenizer = new StringTokenizer(paramString, String.valueOf(paramChar));
    Vector localVector = new Vector(10);
    while (localStringTokenizer.hasMoreTokens())
      localVector.appendElement(localStringTokenizer.nextToken());
    if (localVector.size() == 0)
      return null;
    return localVector;
  }

  public String pathToFile(String paramString)
  {
    String str = System.getProperty("file.separator");
    int i = paramString.lastIndexOf(str);
    if (i == -1)
      return "." + System.getProperty("file.separator");
    return paramString.substring(0, i + 1);
  }

  protected void processArguments(String[] paramArrayOfString)
  {
    for (int i = 0; i < paramArrayOfString.length; ++i)
      if (paramArrayOfString[i].equals("-diagnostic"))
      {
        this.genDiagnostics = true;
        this.genHTML = false;
        setArgOK(i);
      }
      else if (paramArrayOfString[i].equals("-o"))
      {
        setArgOK(i);
        if (i + 1 >= paramArrayOfString.length)
        {
          error("missing output directory with -o option; ignoring");
        }
        else
        {
          setOutputDirectory(paramArrayOfString[(++i)]);
          setArgOK(i);
        }
      }
      else if (paramArrayOfString[i].equals("-html"))
      {
        this.genHTML = true;
        this.genDiagnostics = false;
        setArgOK(i);
      }
      else if (paramArrayOfString[i].equals("-docbook"))
      {
        this.genDocBook = true;
        this.genDiagnostics = false;
        setArgOK(i);
      }
      else if (paramArrayOfString[i].charAt(0) != '-')
      {
        this.grammarFile = paramArrayOfString[i];
        setArgOK(i);
      }
  }

  public void setArgOK(int paramInt)
  {
    this.cmdLineArgValid.add(paramInt);
  }

  public void setOutputDirectory(String paramString)
  {
    this.outputDir = paramString;
  }

  public void toolError(String paramString)
  {
    System.err.println("error: " + paramString);
  }

  public void warning(String paramString)
  {
    System.err.println("warning: " + paramString);
  }

  public void warning(String paramString1, String paramString2, int paramInt1, int paramInt2)
  {
    System.err.println(FileLineFormatter.getFormatter().getFormatString(paramString2, paramInt1, paramInt2) + "warning:" + paramString1);
  }

  public void warning(String[] paramArrayOfString, String paramString, int paramInt1, int paramInt2)
  {
    if ((paramArrayOfString == null) || (paramArrayOfString.length == 0))
      panic("bad multi-line message to Tool.warning");
    System.err.println(FileLineFormatter.getFormatter().getFormatString(paramString, paramInt1, paramInt2) + "warning:" + paramArrayOfString[0]);
    for (int i = 1; i < paramArrayOfString.length; ++i)
      System.err.println(FileLineFormatter.getFormatter().getFormatString(paramString, paramInt1, paramInt2) + "    " + paramArrayOfString[i]);
  }

  public void setNameSpace(String paramString)
  {
    if (null == this.nameSpace)
      this.nameSpace = new NameSpace(StringUtils.stripFrontBack(paramString, "\"", "\""));
  }
}